<!doctype html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <title>XML编辑格式化工具</title>
  <script src="./lib/jquery-3.6.0.min.js"></script>
  <script src="./lib/jquery.format.js"></script>

  <link rel="stylesheet" href="assets/css/bootstrap.min.css">
  <script src="assets/js/bootstrap.min.js"></script>

  <link rel="stylesheet" href="./lib/codemirror.css">
  <link rel="stylesheet" href="./addon/hint/show-hint.css">
  <script src="./lib/codemirror.js"></script>
  <script src="./addon/hint/show-hint.js"></script>
  <script src="./addon/hint/xml-hint.js"></script>
  <script src="./mode/xml/xml.js"></script>

  <style>
    .CodeMirror {
      border: 0px solid #eee;
      width: 100%;
      height: 100%;
    }
  </style>

  <style>
    html {
      width: 100%;
      height: 100%;
    }

    body {
      width: 100%;
      height: 100%;
    }

    #bt {
      margin-top: 0px;
      padding-left: 3px;
      padding-top: 3px;
      margin-bottom: 0px;
      padding-bottom0px;
      width: 100%;
      height: 36px;
      background-color: #3883FA;
    }

    .form-control {
      border-radius: 0px;
    }

    .font-format,
    .font-format:focus,
    .font-format:hover {
      font-size: 14px;
      font-family: monospace;
    }

    #content {
      height: -webkit-calc(100vh - 36px);
      height: -moz-calc(100vh - 36px);
      height: calc(100vh - 36px);
    }
  </style>
</head>

<body>
  <div id="bt">
    <input type="button" value="格式化XML" style="width: 120px;margin-right:2px;margin-left:4px; " onclick="convertFormat()"
      class="btn  btn-sm   btn-danger" />
    <input type="button" value="压缩XML"  style="margin-right:2px;margin-left:2px; " onclick="convertRemoveSpace()" class="btn btn-sm  btn-success " />
    <input type="button" value="清空数据" style="margin-right:2px;margin-left:2px; " onclick="convertClear()" class="btn  btn-sm btn-dark" />
  </div>
  <div id="content">
    <textarea id="code" name="code" autofocus
      style="width: 100%; height: 100% ;overflow: auto;word-break: break-all; resize: none;">
</textarea>
    <script>
      var dummy = {
        attrs: {
          color: ["red", "green", "blue", "purple", "white", "black", "yellow"],
          size: ["large", "medium", "small"],
          description: null
        },
        children: []
      };

      var tags = {
        "!top": ["top"],
        "!attrs": {
          id: null,
          class: ["A", "B", "C"]
        },
        top: {
          attrs: {
            lang: ["en", "de", "fr", "nl"],
            freeform: null
          },
          children: ["animal", "plant"]
        },
        animal: {
          attrs: {
            name: null,
            isduck: ["yes", "no"]
          },
          children: ["wings", "feet", "body", "head", "tail"]
        },
        plant: {
          attrs: { name: null },
          children: ["leaves", "stem", "flowers"]
        },
        wings: dummy, feet: dummy, body: dummy, head: dummy, tail: dummy,
        leaves: dummy, stem: dummy, flowers: dummy
      };

      function completeAfter(cm, pred) {
        var cur = cm.getCursor();
        if (!pred || pred()) setTimeout(function () {
          if (!cm.state.completionActive)
            cm.showHint({ completeSingle: false });
        }, 100);
        return CodeMirror.Pass;
      }

      function completeIfAfterLt(cm) {
        return completeAfter(cm, function () {
          var cur = cm.getCursor();
          return cm.getRange(CodeMirror.Pos(cur.line, cur.ch - 1), cur) == "<";
        });
      }

      function completeIfInTag(cm) {
        return completeAfter(cm, function () {
          var tok = cm.getTokenAt(cm.getCursor());
          if (tok.type == "string" && (!/['"]/.test(tok.string.charAt(tok.string.length - 1)) || tok.string.length == 1)) return false;
          var inner = CodeMirror.innerMode(cm.getMode(), tok.state).state;
          return inner.tagName;
        });
      }


      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
        mode: "xml",
        lineNumbers: true,
        lineWrapping: false,
        extraKeys: {
          "'<'": completeAfter,
          "'/'": completeIfAfterLt,
          "' '": completeIfInTag,
          "'='": completeIfInTag,
          "Ctrl-Space": "autocomplete"
        },
        hintOptions: { schemaInfo: tags }
      });


      function convertFormat() {
        editor.setValue($.format(editor.getValue(), { method: 'xml' }))
      }

      function convertClear() {
        editor.setValue("")
      }

      function convertRemoveSpace() {
        editor.setValue($.format(editor.getValue(), { method: 'xmlmin' }).replace(/[\r\n]/g, ''))
      }

    </script>
  </div>
</body>

</html>